package com.zwb.demo.easyweb.modules.database.service.impl;

import com.zwb.demo.easyweb.common.entity.response.CommonCode;
import com.zwb.demo.easyweb.common.entity.response.ResponseResult;
import com.zwb.demo.easyweb.core.exception.ExceptionCast;
import com.zwb.demo.easyweb.core.utils.ConvertUtils;
import com.zwb.demo.easyweb.modules.database.entity.DatabaseCode;
import com.zwb.demo.easyweb.modules.database.entity.DatabaseLinkPO;
import com.zwb.demo.easyweb.modules.database.entity.DatabaseType;
import com.zwb.demo.easyweb.modules.database.repository.DatabaseLinkPORepository;
import com.zwb.demo.easyweb.modules.database.service.DatabaseLinkService;
import com.zwb.demo.easyweb.modules.database.vo.DatabaseLinkVO;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.List;
import java.util.Optional;

@Service
@Slf4j
public class DatabaseLinkServiceImpl implements DatabaseLinkService {

    private final DatabaseLinkPORepository databaseLinkPORepository;

    @Autowired
    public DatabaseLinkServiceImpl(DatabaseLinkPORepository databaseLinkPORepository) {
        this.databaseLinkPORepository = databaseLinkPORepository;
    }

    @Override
    public ResponseResult findAll() {
        List<DatabaseLinkPO> allPO = databaseLinkPORepository.findAll();
        List<DatabaseLinkVO> allVo = ConvertUtils.convertList(allPO, DatabaseLinkVO.class);
        return ResponseResult.ok().body(allVo);
    }

    @Override
    public ResponseResult save(DatabaseLinkVO vo) {
        DatabaseLinkPO save;
        if (StringUtils.isBlank(vo.getId())) {
            DatabaseLinkPO po = ConvertUtils.convertObject(vo, DatabaseLinkPO.class);
            save = databaseLinkPORepository.save(po);
        } else {
            Optional<DatabaseLinkPO> optional = databaseLinkPORepository.findById(vo.getId());
            if (optional.isPresent()) {
                DatabaseLinkPO po = optional.get();
                BeanUtils.copyProperties(vo, po);
                save = databaseLinkPORepository.save(po);
            } else {
                return new ResponseResult(CommonCode.ID_NO_EXITS);
            }
        }

        return ResponseResult.ok().body(save);
    }

    @Override
    public ResponseResult delete(String id) {
        Optional<DatabaseLinkPO> optional = databaseLinkPORepository.findById(id);
        if (optional.isPresent()) {
            databaseLinkPORepository.deleteById(id);
            return ResponseResult.ok();
        }
        return new ResponseResult(CommonCode.ID_NO_EXITS);
    }

    @Override
    public ResponseResult testLink(DatabaseLinkVO vo) {
        ResponseResult body = null;
        try {
            DatabaseType databaseType = DatabaseType.typeOf(vo.getDatabaseType());
            if (databaseType == null) {
                ExceptionCast.cast(DatabaseCode.NO_EXIT_DATABASE_TYPE);
            }
            Class.forName(databaseType.driverName());
            String url = databaseType.url(vo);
            @Cleanup
            Connection connection = DriverManager.getConnection(url, vo.getUsername(), vo.getPassword());
            body = ResponseResult.ok().body(connection != null);
        } catch (Exception e) {
            body = ResponseResult.fail().message(e.getMessage());
        }
        return body;
    }
}
